from .base_stats import *
import numpy as np
import cv2

class ImagePublic():
	@staticmethod
	def get_image_rect(image: list[list[float]], i: int) -> list[float]:
		w, h = len(image[0]), len(image)
		'''
		获取图片的矩形环
		'''
		# 计算旋转像素
		# 对整个环旋转offset个像素
		# 将环内数据放到一个数组中
		points: list[float] = []
		for x in range(i, w - i): # 顶端
			points.append(image[i][x])
		for y in range(i + 1, h - i): # 右侧
			points.append(image[y][w - i - 1])
		for x in range(w - i - 2, i - 1, -1): # 底部
			points.append(image[h - i - 1][x])
		for y in range(h - i - 2, i, -1): # 左侧
			points.append(image[y][i])
		return points
	
	@staticmethod
	def set_image_rect(image: list[list[float]], i: int, rect: list[float]) -> None:
		w, h = len(image[0]), len(image)
		j = 0
		for x in range(i, w - i): # 顶端
			image[i][x] = rect[j]
			j += 1
		for y in range(i + 1, h - i): # 右侧
			image[y][w - i - 1] = rect[j]
			j += 1
		for x in range(w - i - 2, i - 1, -1): # 底部
			image[h - i - 1][x] = rect[j]
			j += 1
		for y in range(h - i - 2, i, -1): # 左侧
			image[y][i] = rect[j]
			j += 1


	@staticmethod
	def rotate_image(image: list[list[float]], angle: float) -> list[list[float]]: # type: ignore
		w, h = len(image[0]), len(image)
		r:int = np.min([w // 2, h // 2])
		rotated: list[list[float]] = [[0 for _ in range(w)] for _ in range(h)]
		for i in range(r):
			# 将环内数据放到一个数组中
			points: list[float] = ImagePublic.get_image_rect(image, i)
			# 将angle转换为0-360度
			angle = angle % 360
			# 计算旋转像素
			offset = int(len(points) * angle / 360)
			# 旋转环内数据
			rotated_points: list[float] = points[offset:] + points[:offset]
			# 设置旋转后的环
			ImagePublic.set_image_rect(rotated, i, rotated_points)
		return rotated
	
	@staticmethod
	def gradient_img(img: list[list[float]]):
		# Sobel算子计算梯度
		grad_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)  # x方向
		grad_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)  # y方向
		# 取绝对值和转换为8位图像
		abs_grad_x = cv2.convertScaleAbs(grad_x)
		abs_grad_y = cv2.convertScaleAbs(grad_y)

		# 合并两个方向的梯度
		grad_combined = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)

		return grad_combined